home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / python / maclibunix.shar < prev    next >
Encoding:
Text File  |  1994-04-01  |  37.7 KB  |  1,530 lines  |  [TEXT/R*ch]

  1. #! /bin/sh
  2. # This is a shell archive.  Remove anything before this line, then unpack
  3. # it by saving it into a file and typing "sh file".  To overwrite existing
  4. # files, type "sh file -c".  You can also feed this as standard input via
  5. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  6. # will see the following message at the end:
  7. #        "End of archive 1 (of 1)."
  8. # Contents:  MANIFEST Makefile README abort.c access.c chdir.c ctime.c
  9. #   del.c dir.h getbootvol.c getwd.c intercept.h localtime.c ls.c
  10. #   macdefs.h mkdir.c mov.c opendir.c perror.c pwd.c rename.c rmdir.c
  11. #   set_open_hook.c stat.c stat.h sync.c time.c time.h
  12. # Wrapped by guido@dahlia.cwi.nl on Thu Jan 21 16:49:41 1993
  13. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  14. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  15.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  16. else
  17. echo shar: Extracting \"'MANIFEST'\" \(982 characters\)
  18. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  19. X   File Name        Archive #    Description
  20. X-----------------------------------------------------------
  21. X MANIFEST                   1    This shipping list
  22. X Makefile                   1    
  23. X README                     1    
  24. X abort.c                    1    
  25. X access.c                   1    
  26. X chdir.c                    1    
  27. X ctime.c                    1    
  28. X del.c                      1    
  29. X dir.h                      1    
  30. X getbootvol.c               1    
  31. X getwd.c                    1    
  32. X intercept.h                1    
  33. X localtime.c                1    
  34. X ls.c                       1    
  35. X macdefs.h                  1    
  36. X mkdir.c                    1    
  37. X mov.c                      1    
  38. X opendir.c                  1    
  39. X perror.c                   1    
  40. X pwd.c                      1    
  41. X rename.c                   1    
  42. X rmdir.c                    1    
  43. X set_open_hook.c            1    
  44. X stat.c                     1    
  45. X stat.h                     1    
  46. X sync.c                     1    
  47. X time.c                     1    
  48. X time.h                     1    
  49. END_OF_FILE
  50. if test 982 -ne `wc -c <'MANIFEST'`; then
  51.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  52. fi
  53. # end of 'MANIFEST'
  54. fi
  55. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  56.   echo shar: Will not clobber existing file \"'Makefile'\"
  57. else
  58. echo shar: Extracting \"'Makefile'\" \(790 characters\)
  59. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  60. XCOptions=    -g
  61. X
  62. Xall=    abort.c.o ∂
  63. X    access.c.o ∂
  64. X    chdir.c.o ∂
  65. X    ctime.c.o ∂
  66. X    getbootvol.c.o ∂
  67. X    getwd.c.o ∂
  68. X    localtime.c.o ∂
  69. X    mkdir.c.o ∂
  70. X    opendir.c.o ∂
  71. X    perror.c.o ∂
  72. X    rename.c.o ∂
  73. X    rmdir.c.o ∂
  74. X    set_open_hook.c.o ∂
  75. X    stat.c.o ∂
  76. X    sync.c.o ∂
  77. X    time.c.o
  78. X    
  79. X
  80. Xlib.o ƒ {all}
  81. X    lib -o lib.o -sn Main=unixemu {all}
  82. X
  83. Xlibes=    {CLibraries}CInterface.o ∂
  84. X    {CLibraries}CRuntime.o ∂
  85. X    {CLibraries}CSANELib.o ∂
  86. X    {CLibraries}StdCLib.o
  87. X
  88. Xpobjs=    pwd.c.o lib.o
  89. Xpwd    ƒ {pobjs}
  90. X    link -ot MPST -oc 'MPS ' -p -o pwd {pobjs} {libes}
  91. X
  92. Xlobjs=    ls.c.o dir.c.o stat.c.o
  93. Xls    ƒ {lobjs}
  94. X    link -ot MPST -oc 'MPS ' -o ls {lobjs} {libes}
  95. X
  96. Xmobjs=    mov.c.o rename.c.o perror.c.o
  97. Xmov    ƒ {mobjs}
  98. X    link -ot MPST -oc 'MPS ' -o mov {mobjs} {libes}
  99. X
  100. Xdobjs=    del.c.o rename.c.o perror.c.o
  101. Xdel    ƒ {dobjs}
  102. X    link -ot MPST -oc 'MPS ' -o del {dobjs} {libes}
  103. END_OF_FILE
  104. echo shar: 23 control characters may be missing from \"'Makefile'\"
  105. if test 790 -ne `wc -c <'Makefile'`; then
  106.     echo shar: \"'Makefile'\" unpacked with wrong size!
  107. fi
  108. # end of 'Makefile'
  109. fi
  110. if test -f 'README' -a "${1}" != "-c" ; then 
  111.   echo shar: Will not clobber existing file \"'README'\"
  112. else
  113. echo shar: Extracting \"'README'\" \(1959 characters\)
  114. sed "s/^X//" >'README' <<'END_OF_FILE'
  115. XHere's source code for a library of routines for users of MPW C and
  116. XTHINK C (and possibly other C compilers) that makes it somewhat easier
  117. Xto port Unix programs, or at least to write Unix programs that are
  118. Xeasily portable to the Macintosh.
  119. X
  120. XMore-or-less Unix-compatible routines currently provided by this package:
  121. X    abort()
  122. X    access()
  123. X    chdir()
  124. X    ctime()
  125. X    getwd()
  126. X    mkdir()
  127. X    opendir(), readdir(), closedir()
  128. X    perror()
  129. X    rmdir()
  130. X    stat()
  131. X    sync()
  132. X    time(), localtime()
  133. X    
  134. XNote: I've last used this with MPW version 2.0; MPW version 3.x may
  135. Xinclude most of these in its own library.  THINK C 5.0 includes
  136. Xseveral, but these are still needed: chdir(), getwd(), mkdir(),
  137. Xopendir() and friends, rmdir(), stat(), sync().  The same is true for
  138. XTHINK C 4.0 (you may have to tweak the source in minor ways to get it
  139. Xto compile there).
  140. X
  141. XI've also included a routine to get the name of the boot volume, and a
  142. Xway to set a hook in MPW's open routine, which can be used to set the
  143. Xtype of all files created to `TEXT'.  This was also last tested in MPW
  144. X2.0.
  145. X
  146. XFinally, there are two simple example programs (a columnizing `ls' and
  147. X`pwd', both to be run as MPW tools) and a Makefile.  Note that the
  148. XMakefile contains non-ASCII characters and thus may be mangled by
  149. Xmailers; it should however be easy enough to reconstruct it if you know
  150. Xwhat an MPW Makefile should look like.
  151. X
  152. XAll routines work on MFS and HFS (but don't know about MFS folders); no
  153. Xguarantees for Mac SE and Mac II although I don't expect problems (most
  154. Xthings I do are just file system calls).
  155. X
  156. XI hope that the files are sufficiently commented, and moust routines are
  157. Xsufficiently well-known, that no additional documentation is necessary.
  158. X
  159. XBeing sick and tired of copyright wars I hereby place this code in the
  160. Xpublic domain, although it would still be nice if my name remained in
  161. Xredistributed or changed copies of the source.
  162. X
  163. XGuido van Rossum
  164. XCWI, dept. AA
  165. XKruislaan 413
  166. X1098 SJ  Amsterdam
  167. X
  168. XE-mail: guido@cwi.nl
  169. END_OF_FILE
  170. if test 1959 -ne `wc -c <'README'`; then
  171.     echo shar: \"'README'\" unpacked with wrong size!
  172. fi
  173. # end of 'README'
  174. fi
  175. if test -f 'abort.c' -a "${1}" != "-c" ; then 
  176.   echo shar: Will not clobber existing file \"'abort.c'\"
  177. else
  178. echo shar: Extracting \"'abort.c'\" \(146 characters\)
  179. sed "s/^X//" >'abort.c' <<'END_OF_FILE'
  180. X/* Abort emulator.
  181. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  182. X
  183. X#include "macdefs.h"
  184. X
  185. Xabort()
  186. X{
  187. X    Debugger();
  188. X    exit(2);
  189. X}
  190. END_OF_FILE
  191. if test 146 -ne `wc -c <'abort.c'`; then
  192.     echo shar: \"'abort.c'\" unpacked with wrong size!
  193. fi
  194. # end of 'abort.c'
  195. fi
  196. if test -f 'access.c' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'access.c'\"
  198. else
  199. echo shar: Extracting \"'access.c'\" \(953 characters\)
  200. sed "s/^X//" >'access.c' <<'END_OF_FILE'
  201. X/* Macintosh emulation of Unix 'access()' system call.
  202. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  203. X
  204. X   This version ignores the mode flags; it assumes files can always
  205. X   be read or written when they exist.  This is more or less true,
  206. X   except on write-protected volumes and maybe in a shared file system
  207. X   situation.  Note that the Finder's 'locked' bit is ignored by
  208. X   the file system so you can still write such files from within
  209. X   an application.
  210. X   Execute permission might check the file type and return Yes
  211. X   if this is APPL, but I have no use for it right now anyway,
  212. X   so why bother. */
  213. X
  214. X#include "macdefs.h"
  215. X
  216. Xint
  217. Xaccess(path, mode)
  218. X    char *path;
  219. X    int mode;
  220. X{
  221. X    FileParam pb;
  222. X    char name[MAXPATH];
  223. X    
  224. X    strncpy(name, path, sizeof name);
  225. X    pb.ioNamePtr= (StringPtr) c2pstr(name);
  226. X    pb.ioVRefNum= 0;
  227. X    pb.ioFVersNum= 0;
  228. X    pb.ioFDirIndex= 0;
  229. X    if (PBGetFInfo(&pb, FALSE) != noErr) {
  230. X        errno= ENOENT;
  231. X        return -1;
  232. X    }
  233. X    return 0;
  234. X}
  235. END_OF_FILE
  236. if test 953 -ne `wc -c <'access.c'`; then
  237.     echo shar: \"'access.c'\" unpacked with wrong size!
  238. fi
  239. # end of 'access.c'
  240. fi
  241. if test -f 'chdir.c' -a "${1}" != "-c" ; then 
  242.   echo shar: Will not clobber existing file \"'chdir.c'\"
  243. else
  244. echo shar: Extracting \"'chdir.c'\" \(505 characters\)
  245. sed "s/^X//" >'chdir.c' <<'END_OF_FILE'
  246. X/* Chdir for the Macintosh.
  247. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  248. X   Pathnames must be Macintosh paths, with colons as separators. */
  249. X
  250. X#include "macdefs.h"
  251. X
  252. X/* Change current directory. */
  253. X
  254. Xint
  255. Xchdir(path)
  256. X    char *path;
  257. X{
  258. X    WDPBRec pb;
  259. X    char name[MAXPATH];
  260. X    
  261. X    strncpy(name, path, sizeof name);
  262. X    name[MAXPATH-1]= EOS;
  263. X    pb.ioNamePtr= (StringPtr) c2pstr(name);
  264. X    pb.ioVRefNum= 0;
  265. X    pb.ioWDDirID= 0;
  266. X    if (PBHSetVol(&pb, FALSE) != noErr) {
  267. X        errno= ENOENT;
  268. X        return -1;
  269. X    }
  270. X    return 0;
  271. X}
  272. END_OF_FILE
  273. if test 505 -ne `wc -c <'chdir.c'`; then
  274.     echo shar: \"'chdir.c'\" unpacked with wrong size!
  275. fi
  276. # end of 'chdir.c'
  277. fi
  278. if test -f 'ctime.c' -a "${1}" != "-c" ; then 
  279.   echo shar: Will not clobber existing file \"'ctime.c'\"
  280. else
  281. echo shar: Extracting \"'ctime.c'\" \(550 characters\)
  282. sed "s/^X//" >'ctime.c' <<'END_OF_FILE'
  283. X/* Ctime emulator.
  284. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  285. X*/
  286. X
  287. X#include "macdefs.h"
  288. X
  289. Xstatic char dayname[]= "SunMonTueWedThuFriSat";
  290. Xstatic char monthname[]= "JanFebMarAprMayJunJulAugSepOctNovDec";
  291. X
  292. Xchar *
  293. Xctime(secs)
  294. X    long *secs;
  295. X{
  296. X    DateTimeRec date;
  297. X    static char buffer[26];
  298. X    
  299. X    Secs2Date(*secs + TIMEDIFF, &date);
  300. X    sprintf(buffer, "%.3s %.3s %2d %02d:%02d:%02d %4d\n",
  301. X        dayname + 3*(date.dayOfWeek-1),
  302. X        monthname + 3*(date.month-1),
  303. X        date.day,
  304. X        date.hour,
  305. X        date.minute,
  306. X        date.second,
  307. X        date.year);
  308. X    return buffer;
  309. X}
  310. END_OF_FILE
  311. if test 550 -ne `wc -c <'ctime.c'`; then
  312.     echo shar: \"'ctime.c'\" unpacked with wrong size!
  313. fi
  314. # end of 'ctime.c'
  315. fi
  316. if test -f 'del.c' -a "${1}" != "-c" ; then 
  317.   echo shar: Will not clobber existing file \"'del.c'\"
  318. else
  319. echo shar: Extracting \"'del.c'\" \(289 characters\)
  320. sed "s/^X//" >'del.c' <<'END_OF_FILE'
  321. X/* MPW tool to delete a file.
  322. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  323. X
  324. Xmain(argc, argv)
  325. X    int argc;
  326. X    char **argv;
  327. X{
  328. X    if (argc != 2) {
  329. X        printf("usage: %s file\n", argv[0]);
  330. X        exit(2);
  331. X    }
  332. X    if (unlink(argv[1]) != 0) {
  333. X        perror(argv[1]);
  334. X        exit(1);
  335. X    }
  336. X    exit(0);
  337. X}
  338. END_OF_FILE
  339. if test 289 -ne `wc -c <'del.c'`; then
  340.     echo shar: \"'del.c'\" unpacked with wrong size!
  341. fi
  342. # end of 'del.c'
  343. fi
  344. if test -f 'dir.h' -a "${1}" != "-c" ; then 
  345.   echo shar: Will not clobber existing file \"'dir.h'\"
  346. else
  347. echo shar: Extracting \"'dir.h'\" \(357 characters\)
  348. sed "s/^X//" >'dir.h' <<'END_OF_FILE'
  349. X/*
  350. X * "Dir.h" for the Macintosh.
  351. X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  352. X */
  353. X
  354. X#define MAXNAMLEN 31
  355. X#define MAXPATH 256
  356. X
  357. X#define DIR  struct _dir
  358. X
  359. Xstruct _dir {
  360. X    long dirid;
  361. X    int nextfile;
  362. X};
  363. X
  364. Xstruct direct {
  365. X    char d_name[MAXPATH];
  366. X};
  367. X
  368. Xextern DIR *opendir(char *);
  369. Xextern struct direct *readdir(DIR *);
  370. Xextern void closedir(DIR *);
  371. END_OF_FILE
  372. if test 357 -ne `wc -c <'dir.h'`; then
  373.     echo shar: \"'dir.h'\" unpacked with wrong size!
  374. fi
  375. # end of 'dir.h'
  376. fi
  377. if test -f 'getbootvol.c' -a "${1}" != "-c" ; then 
  378.   echo shar: Will not clobber existing file \"'getbootvol.c'\"
  379. else
  380. echo shar: Extracting \"'getbootvol.c'\" \(336 characters\)
  381. sed "s/^X//" >'getbootvol.c' <<'END_OF_FILE'
  382. X/* Return the name of the boot volume (not the current directory).
  383. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  384. X*/
  385. X
  386. X#include "macdefs.h"
  387. X
  388. Xchar *
  389. Xgetbootvol()
  390. X{
  391. X    short vrefnum;
  392. X    static char name[32];
  393. X    
  394. X    (void) GetVol(name, &vrefnum);
  395. X        /* Shouldn't fail; return ":" if it does */
  396. X    strcat(name, ":");
  397. X    return name;
  398. X}
  399. END_OF_FILE
  400. if test 336 -ne `wc -c <'getbootvol.c'`; then
  401.     echo shar: \"'getbootvol.c'\" unpacked with wrong size!
  402. fi
  403. # end of 'getbootvol.c'
  404. fi
  405. if test -f 'getwd.c' -a "${1}" != "-c" ; then 
  406.   echo shar: Will not clobber existing file \"'getwd.c'\"
  407. else
  408. echo shar: Extracting \"'getwd.c'\" \(3404 characters\)
  409. sed "s/^X//" >'getwd.c' <<'END_OF_FILE'
  410. X/* Get full pathname of current working directory.  The pathname is
  411. X   copied to the parameter array 'cwd', and a pointer to this array
  412. X   is also returned as function result.  If an error occurred, however,
  413. X   the return value is NULL but 'cwd' is filled with an error message.
  414. X   
  415. X   BUG: expect spectacular crashes when called from a directory whose
  416. X   path would be over MAXPATH bytes long (files in such directories are
  417. X   not reachable by full pathname).
  418. X   
  419. X   Starting with the dir ID returned by PBHGetVol, we do successive
  420. X   PBGetCatInfo's to get a component of the path until we reach the
  421. X   root (recognized by a dir ID of 2).  We move up along the path
  422. X   using the dir ID of the parent directory returned by PBGetCatInfo.
  423. X   
  424. X   Then we catenate the components found in reverse order with the volume
  425. X   name (already gotten from PBHGetVol), with intervening and trailing
  426. X   colons
  427. X   
  428. X   The code works correctly on MFS disks (where it always returns the
  429. X   volume name) by simply skipping the PBGetCatinfo calls in that case.
  430. X   There is a 'bug' in PBGetCatInfo when called for an MFS disk (with
  431. X   HFS running): it then seems to call PBHGetVInfo, which returns a
  432. X   larger parameter block.  But we won't run into this problem because
  433. X   we never call PBGetCatInfo for the root (assuming that PBHGetVol
  434. X   still sets the root ID in this case).
  435. X
  436. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  437. X*/
  438. X
  439. X#include "macdefs.h"
  440. X
  441. X#define ROOTID 2 /* Root directory ID */
  442. X
  443. Xchar *
  444. Xgetwd(cwd)
  445. X    char *cwd;
  446. X{
  447. X    /* Universal parameter block. */
  448. X    union {
  449. X#ifdef THINK_C
  450. X        HFileInfo f;
  451. X        DirInfo d;
  452. X        WDPBRec w;
  453. X#else /* MPW */
  454. X        struct HFileInfo f;
  455. X        struct DirInfo d;
  456. X        struct WDPBRec w;
  457. X#endif
  458. X    } pb;
  459. X    char buf[MAXPATH]; /* Buffer to store the name components */
  460. X    char *ecwd, *ebuf; /* Pointers to end of used part of cwd and buf */
  461. X    int err; /* Error code of last I/O call */
  462. X    
  463. X    /* First, get the default volume name and working directory ID. */
  464. X    
  465. X    pb.w.ioNamePtr= (unsigned char *)cwd;
  466. X    err= PBHGetVol(&pb.w, FALSE);
  467. X    if (err != noErr) {
  468. X        sprintf(cwd, "I/O error %d in PBHGetVol", err);
  469. X        return NULL;
  470. X    }
  471. X    ecwd= strchr(p2cstr((unsigned char*)cwd), EOS);
  472. X    ebuf= buf;
  473. X    *ebuf = EOS;
  474. X    
  475. X    /* Next, if at least we're running HFS, walk up the path. */
  476. X    
  477. X    if (hfsrunning()) {
  478. X        long dirid= pb.w.ioWDDirID;
  479. X        pb.d.ioVRefNum= pb.w.ioWDVRefNum;
  480. X        while (dirid != ROOTID) {
  481. X            pb.d.ioNamePtr= (unsigned char *) ++ebuf;
  482. X            pb.d.ioFDirIndex= -1;
  483. X            pb.d.ioDrDirID= dirid;
  484. X            err= PBGetCatInfo((CInfoPBPtr)&pb.d, FALSE);
  485. X            if (err != noErr) {
  486. X                sprintf(cwd, "I/O error %d in PBGetCatInfo", err);
  487. X                return NULL;
  488. X            }
  489. X            dirid= pb.d.ioDrParID;
  490. X            ebuf += strlen(p2cstr((unsigned char *)ebuf));
  491. X            /* Should check for buf overflow */
  492. X        }
  493. X    }
  494. X    
  495. X    /* Finally, reverse the list of components and append it to cwd.
  496. X       Ebuf points at the EOS after last component,
  497. X       and there is an EOS before the first component.
  498. X       If there are no components, ebuf equals buf (but there
  499. X       is still an EOS where it points).
  500. X       Ecwd points at the EOS after the path built up so far,
  501. X       initially the volume name.
  502. X       We break out of the loop in the middle, thus
  503. X       appending a colon at the end in all cases. */
  504. X    
  505. X    for (;;) {
  506. X        *ecwd++ = ':';
  507. X        if (ebuf == buf)
  508. X            break;
  509. X        do { } while (*--ebuf != EOS); /* Find component start */
  510. X        strcpy(ecwd, ebuf+1);
  511. X        ecwd= strchr(ecwd, EOS);
  512. X    }
  513. X    *ecwd= EOS;
  514. X    return cwd;
  515. X}
  516. END_OF_FILE
  517. if test 3404 -ne `wc -c <'getwd.c'`; then
  518.     echo shar: \"'getwd.c'\" unpacked with wrong size!
  519. fi
  520. # end of 'getwd.c'
  521. fi
  522. if test -f 'intercept.h' -a "${1}" != "-c" ; then 
  523.   echo shar: Will not clobber existing file \"'intercept.h'\"
  524. else
  525. echo shar: Extracting \"'intercept.h'\" \(1322 characters\)
  526. sed "s/^X//" >'intercept.h' <<'END_OF_FILE'
  527. X/* The structure of the 'device switch' used by the standard I/O library.
  528. X   It is possible to install your own versions of selected routines
  529. X   by storing function pointers into this table.  The structure of
  530. X   the control block for the dev_write function is also given.
  531. X
  532. X   Careful! this information was gathered by disassembling parts
  533. X   of the library.  There are no guarantees that the same code will
  534. X   work in future versions of MPW.
  535. X   Part of it has been tested with versions 1.0B1 trough 2.01.
  536. X   
  537. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  538. X*/
  539. X
  540. Xtypedef int (*funcptr)();    /* Pointer to integer function */
  541. X
  542. Xstruct device {
  543. X    long    dev_name;    /* 'FSYS', 'CONS' or 'SYST' */
  544. X    funcptr    dev_faccess;
  545. X    funcptr dev_close;
  546. X    funcptr dev_read;
  547. X    funcptr dev_write;
  548. X    funcptr dev_ioctl;
  549. X};
  550. X
  551. Xextern struct device _StdDevs[];
  552. X
  553. X#define DEV_FSYS 0
  554. X#define DEV_CONS 1
  555. X#define DEV_SYST 2
  556. X
  557. X/* Control block for dev_write (arg 1 is a pointer to this).
  558. X   You might guess that dev_read is similar. */
  559. X
  560. Xstruct controlblock {
  561. X    long io_filler1;    /* Flags? */
  562. X    long io_filler2;    /* Some pointer */
  563. X    long io_filler3;    /* Zero */
  564. X    long io_nbytes;        /* Number of bytes to write */
  565. X                /* (Reset this to zero after writing) */
  566. X    char *io_data;        /* Start of data buffer */
  567. X};
  568. X
  569. X#define IO_OK 0            /* Return value from dev_write */
  570. END_OF_FILE
  571. if test 1322 -ne `wc -c <'intercept.h'`; then
  572.     echo shar: \"'intercept.h'\" unpacked with wrong size!
  573. fi
  574. # end of 'intercept.h'
  575. fi
  576. if test -f 'localtime.c' -a "${1}" != "-c" ; then 
  577.   echo shar: Will not clobber existing file \"'localtime.c'\"
  578. else
  579. echo shar: Extracting \"'localtime.c'\" \(454 characters\)
  580. sed "s/^X//" >'localtime.c' <<'END_OF_FILE'
  581. X/* Localtime emulator.
  582. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  583. X*/
  584. X
  585. X#include "macdefs.h"
  586. X#include "time.h"
  587. X
  588. Xstruct tm *
  589. Xlocaltime(clock)
  590. X    long *clock;
  591. X{
  592. X    DateTimeRec date;
  593. X    static struct tm t;
  594. X    
  595. X    Secs2Date(*clock + TIMEDIFF, &date);
  596. X    t.tm_sec= date.second;
  597. X    t.tm_min= date.minute;
  598. X    t.tm_hour= date.hour;
  599. X    t.tm_mday= date.day;
  600. X    t.tm_mon= date.month - 1;
  601. X    t.tm_wday= date.dayOfWeek - 1;
  602. X    t.tm_year= date.year - 1900;
  603. X    return &t;
  604. X}
  605. END_OF_FILE
  606. if test 454 -ne `wc -c <'localtime.c'`; then
  607.     echo shar: \"'localtime.c'\" unpacked with wrong size!
  608. fi
  609. # end of 'localtime.c'
  610. fi
  611. if test -f 'ls.c' -a "${1}" != "-c" ; then 
  612.   echo shar: Will not clobber existing file \"'ls.c'\"
  613. else
  614. echo shar: Extracting \"'ls.c'\" \(3872 characters\)
  615. sed "s/^X//" >'ls.c' <<'END_OF_FILE'
  616. X/* An ls-like program for use as an MPW tool.
  617. X   Main improvement over the MPW built-in command Files is columnar
  618. X   output.  Main disadvantage is the absence of a "-l" flag.
  619. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  620. X*/
  621. X
  622. X#include <stdio.h>
  623. X#include "dir.h"
  624. X#include "stat.h"
  625. X
  626. X#include "macdefs.h"
  627. X
  628. Xchar *strcpy();
  629. X
  630. Xint
  631. Xmain(argc, argv)
  632. X    int argc;
  633. X    char **argv;
  634. X{
  635. X    setvbuf(stdout, (char*) NULL, _IOLBF, BUFSIZ);
  636. X    if (argc > 1)
  637. X        lslist(argc-1, argv+1);
  638. X    else
  639. X        lsdir(":");
  640. X    return 0;
  641. X}
  642. X
  643. Xstruct item {
  644. X    char *name;
  645. X    long flags;
  646. X};
  647. X
  648. X#define ISDIR 1        /* flag set for directory */
  649. X
  650. Xint
  651. Xcompare(a, b)
  652. X    struct item *a, *b;
  653. X{
  654. X    return IUMagString(a->name, b->name,
  655. X        strlen(a->name), strlen(b->name));
  656. X}
  657. X
  658. Xoutsortedlist(listc, listv)
  659. X    int listc;
  660. X    struct item *listv;
  661. X{
  662. X    qsort(listv, listc, sizeof(struct item), compare);
  663. X    outlist(listc, listv, 0, 0);
  664. X}
  665. X
  666. Xoutlist(listc, listv, colwidth, screenwidth)
  667. X    int listc;
  668. X    struct item *listv;
  669. X    int colwidth;
  670. X    int screenwidth;
  671. X{
  672. X    int i, j, ncols, nrows;
  673. X    char *p;
  674. X    
  675. X    if (colwidth <= 1) colwidth= 16;
  676. X    if (screenwidth <= 1) screenwidth= 72;
  677. X    ncols= screenwidth/colwidth;
  678. X    nrows= (listc+ncols-1) / ncols;
  679. X    
  680. X    for (i= 0; i < nrows; ++i) {
  681. X        for (j= i; j < listc; j += nrows) {
  682. X            if (listv[j].flags & ISDIR) {
  683. X                char buf[40];
  684. X                sprintf(buf, ":%s:", listv[j].name);
  685. X                p= buf;
  686. X            }
  687. X            else
  688. X                p= listv[j].name;
  689. X            if (j+nrows < listc)
  690. X                printf("%-*.*s ", colwidth, colwidth, p);
  691. X            else
  692. X                printf("%s\n", p);
  693. X        }
  694. X    }
  695. X}
  696. X
  697. Xlslist(argc, argv)
  698. X    int argc;
  699. X    char **argv;
  700. X{
  701. X    struct item *files= NULL;
  702. X    struct item *dirs= NULL;
  703. X    int nfiles= 0;
  704. X    int ndirs= 0;
  705. X    struct stat buf;
  706. X    int i;
  707. X    
  708. X    for (i= 0; i < argc; ++i) {
  709. X        if (isdir(argv[i]))
  710. X            addtolist(argv[i], &dirs, &ndirs, ISDIR);
  711. X        else if (stat(argv[i], &buf) >= 0)
  712. X            addtolist(argv[i], &files, &nfiles, 0);
  713. X        else
  714. X            fprintf(stderr, "Can't stat %s\n", argv[i]);
  715. X    }
  716. X    outsortedlist(nfiles, files);
  717. X    qsort(dirs, ndirs, sizeof(struct item), compare);
  718. X    for (i= 0; i < ndirs; ++i) {
  719. X        printf("\n%s\n", dirs[i]);
  720. X        lsdir(dirs[i]);
  721. X    }
  722. X}
  723. X
  724. X/* "Intelligent" filename concatenation.  Buf becomes path:name, but:
  725. X   insert a SEP only if path doesn't end in SEP and name doesn't
  726. X   begin with SEP; remove a SEP if path ends in SEP and name begins
  727. X   with SEP. Returns buf. */
  728. X
  729. Xchar *
  730. Xmkpath(buf, path, name)
  731. X    char *buf;
  732. X    char *path;
  733. X    char *name;
  734. X{
  735. X    char *p;
  736. X    
  737. X    strcpy(buf, path);
  738. X    p= buf + strlen(buf);
  739. X    if (p > buf) {
  740. X        if (p[-1] != SEP) {
  741. X            if (name[0] != SEP)
  742. X                *p++= SEP;
  743. X        }
  744. X        else if (name[0] == SEP)
  745. X            ++name;
  746. X    }
  747. X    strcpy(p, name);
  748. X    return buf;
  749. X}
  750. X
  751. Xlsdir(dir)
  752. X    char *dir;
  753. X{
  754. X    DIR *dirp= opendir(dir);
  755. X    struct direct *dp;
  756. X    struct item *listv= NULL;
  757. X    int listc= 0;
  758. X    char buf[256];
  759. X    
  760. X    if (dirp == NULL) {
  761. X        fprintf("can't open directory %s\n", dir);
  762. X        return -1;
  763. X    }
  764. X    while ((dp= readdir(dirp)) != NULL)
  765. X        addtolist(dp->d_name, &listv, &listc,
  766. X            isdir(mkpath(buf, dir, dp->d_name)) ? ISDIR : 0);
  767. X    closedir(dirp);
  768. X    if (listc > 0) {
  769. X        outsortedlist(listc, listv);
  770. X        while (--listc >= 0)
  771. X            freemem(listv[listc]);
  772. X        freemem((char*) listv);
  773. X    }
  774. X}
  775. X
  776. Xchar *malloc();
  777. Xchar **realloc();
  778. X
  779. Xchar *
  780. Xgetmem(n)
  781. X    int n;
  782. X{
  783. X    char *p= malloc((unsigned) n);
  784. X    
  785. X    if (p == 0)
  786. X        memexh();
  787. X    return p;
  788. X}
  789. X
  790. Xregetmem(ps, n)
  791. X    char **ps;
  792. X    int n;
  793. X{
  794. X    if (*ps == NULL)
  795. X        *ps= getmem(n);
  796. X    else {
  797. X        *ps= realloc(*ps, (unsigned) n);
  798. X        if (*ps == NULL)
  799. X            memexh();
  800. X    }
  801. X}
  802. X
  803. Xfreemem(p)
  804. X    char *p;
  805. X{
  806. X    free(p);
  807. X}
  808. X
  809. Xmemexh()
  810. X{
  811. X    fprintf(stderr, "out of memory\n");
  812. X    exit(3);
  813. X}
  814. X
  815. Xchar *
  816. Xstrdup(s)
  817. X    char *s;
  818. X{
  819. X    char *p= getmem(strlen(s)+1);
  820. X    
  821. X    return strcpy(p, s);
  822. X}
  823. X
  824. Xaddtolist(s, plistv, plistc, flags)
  825. X    char *s;
  826. X    struct item **plistv;
  827. X    int *plistc;
  828. X    int flags;
  829. X{
  830. X    regetmem(& (char *) *plistv, (*plistc+1) * sizeof(**plistv));
  831. X
  832. X    (*plistv)[*plistc].name= strdup(s);
  833. X    (*plistv)[*plistc].flags= flags;
  834. X    ++*plistc;
  835. X}
  836. X
  837. Xisdir(path)
  838. X    char *path;
  839. X{
  840. X    struct stat buf;
  841. X    
  842. X    return stat(path, &buf) == 0 && (buf.st_mode&S_IFMT) == S_IFDIR;
  843. X}
  844. END_OF_FILE
  845. if test 3872 -ne `wc -c <'ls.c'`; then
  846.     echo shar: \"'ls.c'\" unpacked with wrong size!
  847. fi
  848. # end of 'ls.c'
  849. fi
  850. if test -f 'macdefs.h' -a "${1}" != "-c" ; then 
  851.   echo shar: Will not clobber existing file \"'macdefs.h'\"
  852. else
  853. echo shar: Extracting \"'macdefs.h'\" \(824 characters\)
  854. sed "s/^X//" >'macdefs.h' <<'END_OF_FILE'
  855. X/* Useful #includes and #defines for programming a set of Unix
  856. X   look-alike file system access functions on the Macintosh.
  857. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  858. X*/
  859. X
  860. X#include <Types.h>
  861. X#include <Files.h>
  862. X#include <OSUtils.h>
  863. X
  864. X#include <pascal.h>
  865. X
  866. X#include <errno.h>
  867. X#include <string.h>
  868. X
  869. X/* Difference in origin between Mac and Unix clocks: */
  870. X#define TIMEDIFF ((unsigned long) \
  871. X    (((1970-1904)*365 + (1970-1904)/4) * 24 * 3600))
  872. X
  873. X/* Macro to find out whether we can do HFS-only calls: */
  874. X#define FSFCBLen (* (short *) 0x3f6)
  875. X#define hfsrunning() (FSFCBLen > 0)
  876. X
  877. X/* Universal constants: */
  878. X#define MAXPATH 256
  879. X#define TRUE 1
  880. X#define FALSE 0
  881. X#ifndef NULL
  882. X#define NULL 0
  883. X#endif
  884. X#define EOS '\0'
  885. X#define SEP ':'
  886. X
  887. X#if 0 // doesn't work
  888. X/* Call Macsbug: */
  889. Xpascal void Debugger() extern 0xA9FF;
  890. X#endif
  891. END_OF_FILE
  892. if test 824 -ne `wc -c <'macdefs.h'`; then
  893.     echo shar: \"'macdefs.h'\" unpacked with wrong size!
  894. fi
  895. # end of 'macdefs.h'
  896. fi
  897. if test -f 'mkdir.c' -a "${1}" != "-c" ; then 
  898.   echo shar: Will not clobber existing file \"'mkdir.c'\"
  899. else
  900. echo shar: Extracting \"'mkdir.c'\" \(579 characters\)
  901. sed "s/^X//" >'mkdir.c' <<'END_OF_FILE'
  902. X/* Mkdir for the Macintosh.
  903. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  904. X   Pathnames must be Macintosh paths, with colons as separators. */
  905. X
  906. X#include "macdefs.h"
  907. X
  908. X/* Create a directory. */
  909. X
  910. Xint
  911. Xmkdir(path, mode)
  912. X    char *path;
  913. X    int mode; /* Ignored */
  914. X{
  915. X    HFileParam pb;
  916. X    char name[MAXPATH];
  917. X        
  918. X    if (!hfsrunning()) {
  919. X        errno= ENODEV;
  920. X        return -1;
  921. X    }
  922. X    strncpy(name, path, sizeof name);
  923. X    pb.ioNamePtr= (StringPtr) c2pstr(name);
  924. X    pb.ioVRefNum= 0;
  925. X    pb.ioDirID= 0;
  926. X    if (PBDirCreate((HParmBlkPtr)&pb, FALSE) != noErr) {
  927. X        errno= EACCES;
  928. X        return -1;
  929. X    }
  930. X    return 0;
  931. X}
  932. END_OF_FILE
  933. if test 579 -ne `wc -c <'mkdir.c'`; then
  934.     echo shar: \"'mkdir.c'\" unpacked with wrong size!
  935. fi
  936. # end of 'mkdir.c'
  937. fi
  938. if test -f 'mov.c' -a "${1}" != "-c" ; then 
  939.   echo shar: Will not clobber existing file \"'mov.c'\"
  940. else
  941. echo shar: Extracting \"'mov.c'\" \(307 characters\)
  942. sed "s/^X//" >'mov.c' <<'END_OF_FILE'
  943. X/* MPW tool to move a file.
  944. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  945. X
  946. Xmain(argc, argv)
  947. X    int argc;
  948. X    char **argv;
  949. X{
  950. X    if (argc != 3) {
  951. X        printf("usage: %s oldname newname\n", argv[0]);
  952. X        exit(2);
  953. X    }
  954. X    if (rename(argv[1], argv[2]) != 0) {
  955. X        perror(argv[1]);
  956. X        exit(1);
  957. X    }
  958. X    exit(0);
  959. X}
  960. END_OF_FILE
  961. if test 307 -ne `wc -c <'mov.c'`; then
  962.     echo shar: \"'mov.c'\" unpacked with wrong size!
  963. fi
  964. # end of 'mov.c'
  965. fi
  966. if test -f 'opendir.c' -a "${1}" != "-c" ; then 
  967.   echo shar: Will not clobber existing file \"'opendir.c'\"
  968. else
  969. echo shar: Extracting \"'opendir.c'\" \(1864 characters\)
  970. sed "s/^X//" >'opendir.c' <<'END_OF_FILE'
  971. X/*
  972. X * Macintosh version of UNIX directory access package
  973. X * (opendir, readdir, closedir).
  974. X * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  975. X */
  976. X
  977. X#include "dir.h"
  978. X#include "macdefs.h"
  979. X
  980. Xstatic DIR opened;
  981. X
  982. X/*
  983. X * Open a directory.  This means calling PBOpenWD.
  984. X * The value returned is always the address of opened, or NULL.
  985. X * (I have as yet no use for multiple open directories; this could
  986. X * be implemented by allocating memory dynamically.)
  987. X */
  988. X
  989. XDIR *
  990. Xopendir(path)
  991. X    char *path;
  992. X{
  993. X    union {
  994. X        WDPBRec d;
  995. X        VolumeParam v;
  996. X    } pb;
  997. X    char ppath[MAXPATH];
  998. X    short err;
  999. X    
  1000. X    if (opened.nextfile != 0) {
  1001. X        errno = EBUSY;
  1002. X        return NULL; /* A directory is already open. */
  1003. X    }
  1004. X    strncpy(ppath+1, path, ppath[0]= strlen(path));
  1005. X    pb.d.ioNamePtr= (unsigned char *)ppath;
  1006. X    pb.d.ioVRefNum= 0;
  1007. X    if (hfsrunning()) {
  1008. X        pb.d.ioWDProcID= 0;
  1009. X        pb.d.ioWDDirID= 0;
  1010. X        err= PBOpenWD((WDPBPtr)&pb, FALSE);
  1011. X    }
  1012. X    else {
  1013. X        pb.v.ioVolIndex= 0;
  1014. X        err= PBGetVInfo((ParmBlkPtr)&pb, FALSE);
  1015. X    }
  1016. X    if (err != noErr) {
  1017. X        errno = ENOENT;
  1018. X        return NULL;
  1019. X    }
  1020. X    opened.dirid= pb.d.ioVRefNum;
  1021. X    opened.nextfile= 1;
  1022. X    return &opened;
  1023. X}
  1024. X
  1025. X/*
  1026. X * Close a directory.
  1027. X */
  1028. X
  1029. Xvoid
  1030. Xclosedir(dirp)
  1031. X    DIR *dirp;
  1032. X{
  1033. X    if (hfsrunning()) {
  1034. X        WDPBRec pb;
  1035. X        
  1036. X        pb.ioVRefNum= dirp->dirid;
  1037. X        (void) PBCloseWD(&pb, FALSE);
  1038. X    }
  1039. X    dirp->dirid= 0;
  1040. X    dirp->nextfile= 0;
  1041. X}
  1042. X
  1043. X/*
  1044. X * Read the next directory entry.
  1045. X */
  1046. X
  1047. Xstruct direct *
  1048. Xreaddir(dp)
  1049. X    DIR *dp;
  1050. X{
  1051. X    union {
  1052. X        DirInfo d;
  1053. X        FileParam f;
  1054. X        HFileInfo hf;
  1055. X    } pb;
  1056. X    short err;
  1057. X    static struct direct dir;
  1058. X    
  1059. X    dir.d_name[0]= 0;
  1060. X    pb.d.ioNamePtr= (unsigned char *)dir.d_name;
  1061. X    pb.d.ioVRefNum= dp->dirid;
  1062. X    pb.d.ioFDirIndex= dp->nextfile++;
  1063. X    pb.d.ioDrDirID= 0;
  1064. X    if (hfsrunning())
  1065. X        err= PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
  1066. X    else
  1067. X        err= PBGetFInfo((ParmBlkPtr)&pb, FALSE);
  1068. X    if (err != noErr) {
  1069. X        errno = EIO;
  1070. X        return NULL;
  1071. X    }
  1072. X    (void) p2cstr((unsigned char *)dir.d_name);
  1073. X    return &dir;
  1074. X}
  1075. END_OF_FILE
  1076. if test 1864 -ne `wc -c <'opendir.c'`; then
  1077.     echo shar: \"'opendir.c'\" unpacked with wrong size!
  1078. fi
  1079. # end of 'opendir.c'
  1080. fi
  1081. if test -f 'perror.c' -a "${1}" != "-c" ; then 
  1082.   echo shar: Will not clobber existing file \"'perror.c'\"
  1083. else
  1084. echo shar: Extracting \"'perror.c'\" \(246 characters\)
  1085. sed "s/^X//" >'perror.c' <<'END_OF_FILE'
  1086. X/* Perror emulator.
  1087. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1088. X
  1089. X#include <stdio.h>
  1090. X#include <errno.h>
  1091. X
  1092. Xperror(str)
  1093. X    char *str;
  1094. X{
  1095. X    if (str != NULL)
  1096. X        fprintf(stderr, "%s: ", str);
  1097. X    fprintf(stderr, "Error %d\n", errno);
  1098. X}
  1099. END_OF_FILE
  1100. if test 246 -ne `wc -c <'perror.c'`; then
  1101.     echo shar: \"'perror.c'\" unpacked with wrong size!
  1102. fi
  1103. # end of 'perror.c'
  1104. fi
  1105. if test -f 'pwd.c' -a "${1}" != "-c" ; then 
  1106.   echo shar: Will not clobber existing file \"'pwd.c'\"
  1107. else
  1108. echo shar: Extracting \"'pwd.c'\" \(271 characters\)
  1109. sed "s/^X//" >'pwd.c' <<'END_OF_FILE'
  1110. X/* PWD tool to print working directory.
  1111. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1112. X
  1113. X#include <stdio.h>
  1114. X
  1115. Xmain()
  1116. X{
  1117. X    char buffer[256];
  1118. X    
  1119. X    if (getwd(buffer) == NULL) {
  1120. X        fprintf(stderr, "pwd: %s\n", buffer);
  1121. X        exit(1);
  1122. X    }
  1123. X    puts(buffer);
  1124. X    exit(0);
  1125. X}
  1126. END_OF_FILE
  1127. if test 271 -ne `wc -c <'pwd.c'`; then
  1128.     echo shar: \"'pwd.c'\" unpacked with wrong size!
  1129. fi
  1130. # end of 'pwd.c'
  1131. fi
  1132. if test -f 'rename.c' -a "${1}" != "-c" ; then 
  1133.   echo shar: Will not clobber existing file \"'rename.c'\"
  1134. else
  1135. echo shar: Extracting \"'rename.c'\" \(229 characters\)
  1136. sed "s/^X//" >'rename.c' <<'END_OF_FILE'
  1137. X/* Rename emulator.
  1138. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1139. X
  1140. X#include "macdefs.h"
  1141. X
  1142. Xint
  1143. Xrename(old, new)
  1144. X    char *old, *new;
  1145. X{
  1146. X    if (Rename(old, 0, new) == noErr)
  1147. X        return 0;
  1148. X    errno= EPERM;
  1149. X    return -1;
  1150. X}
  1151. END_OF_FILE
  1152. if test 229 -ne `wc -c <'rename.c'`; then
  1153.     echo shar: \"'rename.c'\" unpacked with wrong size!
  1154. fi
  1155. # end of 'rename.c'
  1156. fi
  1157. if test -f 'rmdir.c' -a "${1}" != "-c" ; then 
  1158.   echo shar: Will not clobber existing file \"'rmdir.c'\"
  1159. else
  1160. echo shar: Extracting \"'rmdir.c'\" \(442 characters\)
  1161. sed "s/^X//" >'rmdir.c' <<'END_OF_FILE'
  1162. X/* Rmdir for the Macintosh.
  1163. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  1164. X   Pathnames must be Macintosh paths, with colons as separators. */
  1165. X
  1166. X#include "macdefs.h"
  1167. X
  1168. Xint
  1169. Xrmdir(path)
  1170. X    char *path;
  1171. X{
  1172. X    IOParam pb;
  1173. X    char name[MAXPATH];
  1174. X    
  1175. X    strncpy(name, path, sizeof name);
  1176. X    pb.ioNamePtr= (StringPtr) c2pstr(name);
  1177. X    pb.ioVRefNum= 0;
  1178. X    if (PBDelete((ParmBlkPtr)&pb, FALSE) != noErr) {
  1179. X        errno= EACCES;
  1180. X        return -1;
  1181. X    }
  1182. X    return 0;
  1183. X}
  1184. END_OF_FILE
  1185. if test 442 -ne `wc -c <'rmdir.c'`; then
  1186.     echo shar: \"'rmdir.c'\" unpacked with wrong size!
  1187. fi
  1188. # end of 'rmdir.c'
  1189. fi
  1190. if test -f 'set_open_hook.c' -a "${1}" != "-c" ; then 
  1191.   echo shar: Will not clobber existing file \"'set_open_hook.c'\"
  1192. else
  1193. echo shar: Extracting \"'set_open_hook.c'\" \(3381 characters\)
  1194. sed "s/^X//" >'set_open_hook.c' <<'END_OF_FILE'
  1195. X/* A procedure to install a hook in the MPW C 'open' library function.
  1196. X   This is useful because you may want to create files automatically
  1197. X   with type 'TEXT' without having to change all the 'open' or 'fopen'
  1198. X   calls in a large C program you are trying to port.  A standard hook
  1199. X   procedure for this purpose is also provided.   
  1200. X
  1201. X   Call:
  1202. X       set_open_hook(proc);
  1203. X   This installs the hook proc, or restores the default situation if
  1204. X   proc is NULL.
  1205. X   The hook procedure will be called immediately *after* a successful
  1206. X   open call, with the following parameters:
  1207. X       proc(filename, oflag, fd)
  1208. X        char *filename;        The file name
  1209. X        int oflag;        Mode passed to open
  1210. X        int fd;            Return value from open
  1211. X
  1212. X   Note: this only works when the program is linked as an application
  1213. X   (type APPL); for tools (type MPST) the device switch is located
  1214. X   in the Shell's memory.
  1215. X   
  1216. X   Careful! this information was gathered by disassembling parts
  1217. X   of the library.
  1218. X   There are no guarantees that the same code will work in future
  1219. X   versions of MPW.  It has been tested with versions 1.0B2 through 2.01.
  1220. X   
  1221. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  1222. X*/
  1223. X
  1224. X#include "macdefs.h"
  1225. X#include <fcntl.h>
  1226. X#include "intercept.h"
  1227. X
  1228. X#define ERRFLAG 0x40000000
  1229. X
  1230. Xstatic ProcPtr open_hook;
  1231. X
  1232. X/* The hook for faccess, installed in the device switch.
  1233. X   This will be called with cmd == F_OPEN from 'open',
  1234. X   but also from 'faccess', with other values for cmd.
  1235. X   The open_hook is only called if cmd == F_OPEN.
  1236. X   It is not necessary to check whether open_hook is NULL,
  1237. X   since we are only installed after open_hook is set non-NULL. */
  1238. X
  1239. Xstatic long
  1240. Xmy_faccess(file, cmd, arg)
  1241. X    char *file;
  1242. X    int cmd;
  1243. X    short *arg;
  1244. X{
  1245. X    long res= _fsFAccess(file, cmd, arg);
  1246. X    
  1247. X    if (cmd == F_OPEN && !(res&ERRFLAG)) {
  1248. X        (void) (*open_hook)(file, *arg, (int)res);
  1249. X    }
  1250. X    return res;
  1251. X}
  1252. X
  1253. X/* Standard open hook, to set type and creator of created files.
  1254. X   It will not change existing non-zero type or creator fields.
  1255. X   It returns an error code even though this is ignored by the
  1256. X   calling routine; you might want to call it yourself in a more
  1257. X   fancyful hook, and test the error code.
  1258. X   This routine can be customized by changing 'std_type' or
  1259. X   'std_creator'. */
  1260. X
  1261. XOSType std_type=    'TEXT';
  1262. XOSType std_creator=    'MPS ';
  1263. X
  1264. Xint
  1265. Xstd_open_hook(file, mode, fd)
  1266. X    char *file;
  1267. X    int mode;
  1268. X    int fd;
  1269. X{
  1270. X    FInfo info;
  1271. X    int err= noErr;
  1272. X    
  1273. X    switch (mode & 03) {
  1274. X    
  1275. X    case O_RDWR:
  1276. X    case O_WRONLY:
  1277. X        err= GetFInfo(file, 0, &info);
  1278. X        if (err != noErr)
  1279. X            return err;
  1280. X        if (info.fdType == 0) {
  1281. X            info.fdType= std_type;
  1282. X            ++err; /* Use 'err' as a flag to call SetFInfo */
  1283. X        }
  1284. X        if (info.fdCreator == 0) {
  1285. X            info.fdCreator= std_creator;
  1286. X            ++err;
  1287. X        }
  1288. X        if (err != noErr)
  1289. X            err= SetFInfo(file, 0, &info);
  1290. X    
  1291. X    }
  1292. X    return err;
  1293. X}
  1294. X
  1295. X/* The procedure to install the hook.
  1296. X   Note: this assumes nobody else is also installing hooks
  1297. X   for faccess, otherwise we would have to save and restore
  1298. X   the old function, instead of blindly assuming _fsFAccess. */
  1299. X
  1300. Xset_open_hook(hook)
  1301. X    ProcPtr hook;
  1302. X{
  1303. X    if (hook == NULL)
  1304. X        _StdDevs[DEV_FSYS].dev_faccess= _fsFAccess;
  1305. X    else {
  1306. X        open_hook= hook;
  1307. X        _StdDevs[DEV_FSYS].dev_faccess= my_faccess;
  1308. X    }
  1309. X}
  1310. X
  1311. X/* A trivial test program will be included if you #define MAIN: */
  1312. X
  1313. X#ifdef MAIN
  1314. X
  1315. X#include <stdio.h>
  1316. X
  1317. Xextern int std_open_hook();
  1318. X
  1319. Xmain()
  1320. X{
  1321. X    set_open_hook(std_open_hook);
  1322. X    fclose(fopen("ABC", "a"));
  1323. X}
  1324. X
  1325. X#endif
  1326. END_OF_FILE
  1327. if test 3381 -ne `wc -c <'set_open_hook.c'`; then
  1328.     echo shar: \"'set_open_hook.c'\" unpacked with wrong size!
  1329. fi
  1330. # end of 'set_open_hook.c'
  1331. fi
  1332. if test -f 'stat.c' -a "${1}" != "-c" ; then 
  1333.   echo shar: Will not clobber existing file \"'stat.c'\"
  1334. else
  1335. echo shar: Extracting \"'stat.c'\" \(1246 characters\)
  1336. sed "s/^X//" >'stat.c' <<'END_OF_FILE'
  1337. X/* Minimal 'stat' emulation: tells directories from files and
  1338. X   gives length and mtime.
  1339. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  1340. X*/
  1341. X
  1342. X#include "stat.h"
  1343. X#include "macdefs.h"
  1344. X
  1345. X/* Bits in ioFlAttrib: */
  1346. X#define LOCKBIT    (1<<0)        /* File locked */
  1347. X#define DIRBIT    (1<<4)        /* It's a directory */
  1348. X
  1349. Xint
  1350. Xstat(path, buf)
  1351. X    char *path;
  1352. X    struct stat *buf;
  1353. X{
  1354. X    union {
  1355. X        DirInfo d;
  1356. X        FileParam f;
  1357. X        HFileInfo hf;
  1358. X    } pb;
  1359. X    char name[256];
  1360. X    short err;
  1361. X    
  1362. X    pb.d.ioNamePtr= (unsigned char *)c2pstr(strcpy(name, path));
  1363. X    pb.d.ioVRefNum= 0;
  1364. X    pb.d.ioFDirIndex= 0;
  1365. X    pb.d.ioDrDirID= 0;
  1366. X    pb.f.ioFVersNum= 0; /* Fix found by Timo! See Tech Note 102 */
  1367. X    if (hfsrunning())
  1368. X        err= PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
  1369. X    else
  1370. X        err= PBGetFInfo((ParmBlkPtr)&pb, FALSE);
  1371. X    if (err != noErr) {
  1372. X        errno = ENOENT;
  1373. X        return -1;
  1374. X    }
  1375. X    if (pb.d.ioFlAttrib & LOCKBIT)
  1376. X        buf->st_mode= 0444;
  1377. X    else
  1378. X        buf->st_mode= 0666;
  1379. X    if (pb.d.ioFlAttrib & DIRBIT) {
  1380. X        buf->st_mode |= 0111 | S_IFDIR;
  1381. X        buf->st_size= pb.d.ioDrNmFls;
  1382. X        buf->st_rsize= 0;
  1383. X    }
  1384. X    else {
  1385. X        buf->st_mode |= S_IFREG;
  1386. X        if (pb.f.ioFlFndrInfo.fdType == 'APPL')
  1387. X            buf->st_mode |= 0111;
  1388. X        buf->st_size= pb.f.ioFlLgLen;
  1389. X        buf->st_rsize= pb.f.ioFlRLgLen;
  1390. X    }
  1391. X    buf->st_mtime= pb.f.ioFlMdDat - TIMEDIFF;
  1392. X    return 0;
  1393. X}
  1394. END_OF_FILE
  1395. if test 1246 -ne `wc -c <'stat.c'`; then
  1396.     echo shar: \"'stat.c'\" unpacked with wrong size!
  1397. fi
  1398. # end of 'stat.c'
  1399. fi
  1400. if test -f 'stat.h' -a "${1}" != "-c" ; then 
  1401.   echo shar: Will not clobber existing file \"'stat.h'\"
  1402. else
  1403. echo shar: Extracting \"'stat.h'\" \(412 characters\)
  1404. sed "s/^X//" >'stat.h' <<'END_OF_FILE'
  1405. X/* Include file belonging to stat emulator.
  1406. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1407. X
  1408. Xstruct stat {
  1409. X    unsigned short st_mode;
  1410. X    unsigned long st_size;
  1411. X    unsigned long st_rsize; /* Resource size -- nonstandard */
  1412. X    unsigned long st_mtime;
  1413. X};
  1414. X
  1415. X#define S_IFMT    0170000L
  1416. X#define S_IFDIR    0040000L
  1417. X#define S_IFREG 0100000L
  1418. X#define S_IREAD    0400
  1419. X#define S_IWRITE   0200
  1420. X#define S_IEXEC    0100
  1421. END_OF_FILE
  1422. if test 412 -ne `wc -c <'stat.h'`; then
  1423.     echo shar: \"'stat.h'\" unpacked with wrong size!
  1424. fi
  1425. # end of 'stat.h'
  1426. fi
  1427. if test -f 'sync.c' -a "${1}" != "-c" ; then 
  1428.   echo shar: Will not clobber existing file \"'sync.c'\"
  1429. else
  1430. echo shar: Extracting \"'sync.c'\" \(360 characters\)
  1431. sed "s/^X//" >'sync.c' <<'END_OF_FILE'
  1432. X/* The equivalent of the Unix 'sync' system call: FlushVol.
  1433. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  1434. X   For now, we only flush the default volume
  1435. X   (since that's the only volume written to by MacB). */
  1436. X
  1437. X#include "macdefs.h"
  1438. X
  1439. Xint
  1440. Xsync()
  1441. X{
  1442. X    if (FlushVol((StringPtr)0, 0) == noErr)
  1443. X        return 0;
  1444. X    else {
  1445. X        errno= ENODEV;
  1446. X        return -1;
  1447. X    }
  1448. X}
  1449. END_OF_FILE
  1450. if test 360 -ne `wc -c <'sync.c'`; then
  1451.     echo shar: \"'sync.c'\" unpacked with wrong size!
  1452. fi
  1453. # end of 'sync.c'
  1454. fi
  1455. if test -f 'time.c' -a "${1}" != "-c" ; then 
  1456.   echo shar: Will not clobber existing file \"'time.c'\"
  1457. else
  1458. echo shar: Extracting \"'time.c'\" \(254 characters\)
  1459. sed "s/^X//" >'time.c' <<'END_OF_FILE'
  1460. X/* Time emulator.
  1461. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1462. X
  1463. X#include "macdefs.h"
  1464. X#include <OSUtils.h>
  1465. X
  1466. Xlong
  1467. Xtime(p)
  1468. X    long *p;
  1469. X{
  1470. X    long secs;
  1471. X    
  1472. X    GetDateTime(&secs);
  1473. X    secs -= TIMEDIFF;
  1474. X    if (p != NULL)
  1475. X        *p= secs;
  1476. X    return secs;
  1477. X}
  1478. END_OF_FILE
  1479. if test 254 -ne `wc -c <'time.c'`; then
  1480.     echo shar: \"'time.c'\" unpacked with wrong size!
  1481. fi
  1482. # end of 'time.c'
  1483. fi
  1484. if test -f 'time.h' -a "${1}" != "-c" ; then 
  1485.   echo shar: Will not clobber existing file \"'time.h'\"
  1486. else
  1487. echo shar: Extracting \"'time.h'\" \(293 characters\)
  1488. sed "s/^X//" >'time.h' <<'END_OF_FILE'
  1489. X/* Include file for localtime emulator.
  1490. X   Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). */
  1491. X
  1492. Xstruct tm {
  1493. X    int tm_sec;
  1494. X    int tm_min;
  1495. X    int tm_hour;
  1496. X    int tm_mday;
  1497. X    int tm_mon;
  1498. X    int tm_year;
  1499. X    int tm_wday;
  1500. X    /*
  1501. X    int tm_yday;
  1502. X    int tm_isdst;
  1503. X    */
  1504. X};
  1505. X
  1506. Xstruct tm *gmtime(), *localtime();
  1507. END_OF_FILE
  1508. if test 293 -ne `wc -c <'time.h'`; then
  1509.     echo shar: \"'time.h'\" unpacked with wrong size!
  1510. fi
  1511. # end of 'time.h'
  1512. fi
  1513. echo shar: End of archive 1 \(of 1\).
  1514. cp /dev/null ark1isdone
  1515. MISSING=""
  1516. for I in 1 ; do
  1517.     if test ! -f ark${I}isdone ; then
  1518.     MISSING="${MISSING} ${I}"
  1519.     fi
  1520. done
  1521. if test "${MISSING}" = "" ; then
  1522.     echo You have the archive.
  1523.     rm -f ark[1-9]isdone
  1524. else
  1525.     echo You still need to unpack the following archives:
  1526.     echo "        " ${MISSING}
  1527. fi
  1528. ##  End of shell archive.
  1529. exit 0
  1530.